context("testing the basic operations of community object")

N=100
x=runif(N,0,100)
y=runif(N,0,200)
sp=1:N

test_that("Create a community object",{
  com=community(species=sp,x=x,y=y,plotdim=c(100,200))
  expect_is(com,"community") # a community object
  expect_is(com,"data.frame") #it is also a data.frame
  expect_equal(dim(com),c(N,3)) #the same number of row
  expect_equal(attr(com,"plotdim"),c(100,200))
  
  #an empty community
  com2=community(species=character(),x=numeric(),y=numeric(),plotdim=c(1,1))
  expect_is(com2,"community") # a community object
  expect_equal(dim(com2),c(0,3)) #the same number of row
  expect_equal(attr(com,"plotdim"),c(100,200))
  
  
  #if point on the boundary, it should be included
  bound_test=function(x=0,y=0,sp=1,plotdim=c(100,200)){
    com=community(sp,x,y,plotdim)
  }
  expect_equal(dim(bound_test(x=0,y=0)),c(1,3))
  expect_equal(dim(bound_test(x=100,y=0)),c(1,3))
  expect_equal(dim(bound_test(x=0,y=200)),c(1,3))
  expect_equal(dim(bound_test(x=100,y=200)),c(1,3))
  
  #if location of any points overlap, warning message printed
  expect_warning(bound_test(x=c(1,1),y=c(2,2),sp=1:2),
                 "Some individuals are spatilly overlapped")
  
  #if any points outside the boundary, it should not be included
  expect_warning(com3<-bound_test(x=c(100,101),y=c(50,50),sp=1:2,plotdim=c(100,200)),
                 "some individuals distributed outside the plot")
  expect_equal(dim(com3),c(2,3)) #the error point still left
  
  #the traits information should be individual level and equal length
  trait=data.frame(dbh=1:N,height=N:1)
  expect_error(community(species=sp,x=x,y=y,plotdim=c(100,200),traits=c(dbh=1:N)),
               "the given traits is not a data frame")
  expect_error(community(species=sp,x=x,y=y,plotdim=c(100,200),traits=trait[-1,]),
               "the number of trait row does not equal to the number of individuals")
  com4=community(species=sp,x,y,plotdim = c(100,200),traits=trait)
  expect_equal(dim(com4),c(N,dim(trait)[2]+3))
  expect_true("dbh" %in% colnames(com4))
  expect_true("height" %in% colnames(com4))
  
  expect_equal(get_trait_names(com4),c("dbh","height")) #test the trait names
  expect_equal(get_traits(com4,get_trait_names(com4)),trait)
  
  #test remove trait information
  expect_warning(remove_traits(com4,"dbhs"),
                 "no corresponding trait names have been found")
  expect_warning(remove_traits(com4,c("dbhs","dbh")),
                 "some trait names were not found")
  expect_equal(get_trait_names(remove_traits(com4,"dbh")),"height")
  expect_equal(get_trait_names(remove_traits(com4,"height")),"dbh")
  expect_equal(get_trait_names(remove_traits(com4,c("height","dbh"))),character()) #no trait founded
  
})


test_that("subset a community object",{
  com=community(species=sp,x=x,y=y,plotdim=c(100,200),traits=data.frame(dbh=1:N))
  
  #the subset.community function
  subcom=subset(com,1:5)
  
  expect_is(subcom,"community")
  expect_equal(dim(subcom),c(5,4))
  expect_equal(subcom$x,com$x[1:5])
  expect_equal(subcom$y,com$y[1:5])
  expect_equal(as.character(subcom$species),as.character(com$species[1:5]) )
  expect_equal(levels(subcom$species),levels(as.factor(as.character(com$species[1:5])))) #keep the level information of paranet
  expect_equal(subcom$dbh,com$dbh[1:5])
  
  subcom2=com[11:15,]
  
  expect_is(subcom2,"community")
  expect_equal(dim(subcom2),c(5,4))
  expect_equal(subcom2$x,com$x[11:15])
  expect_equal(subcom2$y,com$y[11:15])
  expect_equal(as.character(subcom2$species),as.character(com$species[11:15]) )
  expect_equal(levels(subcom2$species),levels(as.factor(as.character(com$species[11:15])))) #keep the level information of paranet
  expect_equal(subcom2$dbh,com$dbh[11:15])
  
  #split a community into a list of population
  com=community(species=sample(1:4,N,replace = T),x=x,y=y,plotdim=c(100,200),traits=data.frame(dbh=1:N))
  pops=split(com)
  expect_length(pops,4)
  expect_true(sum(unlist(lapply(pops,nrow)))==nrow(com)) #total individual does not change 
  expect_true(all(unlist(lapply(pops,function(x) "population" %in% class(x))))) #each element is an population object
  expect_true(all(unlist(lapply(pops,function(x) attr(x,"plotdim")==c(100,200) )))) #all population has the same plot dim with the community
  names(pops)=species_list(com) #the name of each element equals to the species name of the population
  
  
  #remove certain species from a community
  splist=c("1","2")
  subcom3=remove_species(com,splist)
  expect_true(nrow(subcom3)<nrow(com))
  expect_true(all(unique(subcom3$species) %in% c("3","4")))
  expect_length(levels(subcom3$species),2)
  
  #remove species with abundance below or equal to minN
  spab=table(com$species)
  minN=min(spab)
  nrm=sum(spab==minN) #number of species with equal minimum abundance
  subcom31=remove_rare_species(com,minN)
  expect_length(levels(subcom31$species),4-nrm) #should be only 4-nrm species left
  expect_true(!all(unlist(lapply(names(which(spab==minN)),function(x) x %in% subcom31$species ))))
  meanN=round(mean(spab),0)
  subcom32=remove_rare_species(com,meanN)
  expect_length(levels(subcom32$species),sum(spab>meanN)) 
  
  #remove certain individuals from a community
  ind_i=sample(1:N,10)
  subcom4=remove_individuals(com,ind_i)
  expect_equal(nrow(subcom4),N-10)
  expect_equal(subcom4$x,com$x[-ind_i]) # order of coordinates should not change
  expect_equal(subcom4$y,com$y[-ind_i])
  # order of the species should be equal too
  expect_equal(as.character(subcom4$species),as.character(com$species[-ind_i]))
  
  #remove spatially overlapped individuals
  expect_warning(com <- community(x=c(1,1,2),  y=c(3,3,2),species=1:3,plotdim=c(10,10)))
  expect_true(is_overlapped(com))
  expect_length(io<-get_overlapped(com),1)
  expect_equal(io[[1]],c(1,2)) #get the correct index of overlapped individuals
  expect_equal(nrow(uniqueness(com)),2) #only to individuals left
  #if no overlap individual exist, just retrun the orginal object
  com2=uniqueness(com)
  expect_equal(uniqueness(com2),com2)
  
  #get a population
  com=community(species=c(rep(1,4),rep(2,6)),x=1:10,y=1:10,plotdim=c(100,200),traits=data.frame(dbh=1:10))
  pop=get_population(com,"1")
  expect_is(pop,"population")
  expect_equal(nrow(pop),4)
  expect_equal(attr(pop,"plotdim"),c(100,200))
  expect_equal(colnames(pop)[3],"dbh")
  
  #get a subcommunity contains several populations
  com=community(species=sp,x=x,y=y,plotdim=c(100,200),traits=data.frame(dbh=1:N))
  subcom=get_populations(com,1:4)
  expect_is(subcom,"community")
  expect_equal(nrow(subcom),4)
  expect_length(levels(subcom$species),4)
  
})

test_that("merge communities into a new community",{
  #merge two simple communities
  com1=community(species=sample(1:4,10,replace = TRUE),x=1:10,y=1:10,plotdim=c(100,100))
  com2=community(species=sample(3:6,15,replace = TRUE),x=11:25,y=11:25,plotdim=c(100,100))
  
  com=merge(com1,com2)
  expect_is(com,"community")
  expect_equal(nrow(com),10+15) #total individual number equals the sum of subcommunities
  allsp=as.character(sort( unique(c(levels(com1$species),levels(com2$species))) ))
  expect_equal(levels(com$species),sort(allsp)) #species list is just from the species pool of com1 and com2
  expect_equal(attr(com,"plotdim"),c(100,100)) #plotdim does not change
  spab1=table(com1$species)
  spab2=table(com2$species)
  spab=rep(0,6)
  spab[as.numeric(names(spab1))]=as.numeric(spab1)
  spab[as.numeric(names(spab2))]=spab[as.numeric(names(spab2))]+as.numeric(spab2)
  spab_obs=rep(0,6)
  spab_obs[as.numeric(names(table(com$species)))]=as.numeric(table(com$species))
  expect_equal(spab_obs,spab) #species abundance did not change
  
  #merge two communities with equal traits
  com3=com1
  com1=community(species=sample(1:4,10,replace = TRUE),x=1:10,y=1:10,plotdim=c(100,100),traits=data.frame(dbh=1:10))
  com2=community(species=sample(3:6,15,replace = TRUE),x=11:25,y=11:25,plotdim=c(100,100),traits=data.frame(dbh=11:25))
  
  #two communities with different number of columns can not merge
  expect_error(merge(com3,com1),
               "Two different structured communities can not be merged")
  
  com=merge(com1,com2)
  expect_is(com,"community")
  expect_equal(dim(com),c(10+15,4)) #has one trait column
  expect_equal(colnames(com)[4],"dbh")
  #should have the same basic summary statistic values
  expect_equal(sum(com$dbh),sum(c(com1$dbh,com2$dbh)))
  expect_equal(mean(com$dbh),mean(c(com1$dbh,com2$dbh)))
  expect_equal(var(com$dbh),var(c(com1$dbh,com2$dbh)))
  
})


